package com.hqs.rxjava;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import com.hqs.common.utils.Log;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class RetryActivity extends AppCompatActivity {

    private int retryTime = 3;
    private int curRetryTime = 0;

    Disposable mDisposable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retry);

        ButterKnife.bind(this);
    }

    @OnClick(R.id.button)
    void click(){
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
                        // 加载数据
                        Log.print("加载数据");
                        Thread.sleep(1000);

                        Random random = new Random();
                        boolean isOk = random.nextBoolean();
                        if (isOk){
                            Log.print("加载数据成功");
                            e.onNext(1);
                            curRetryTime = 0;
                        }
                        else{
                            // 加载数据失败
                            Log.print("加载数据失败");
                            e.onError(new RuntimeException("MyErrorType"));
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {

                                if (throwable.getMessage().contains("MyErrorType")){
                                    if (curRetryTime++ < retryTime) {
                                        // 模拟重试
                                        Log.print("尝试重新获取数据..." + curRetryTime);
                                        return Observable.timer(1000, TimeUnit.MILLISECONDS);
                                    }
                                    curRetryTime = 0;
                                    Log.print("尝试失败!!!");
                                }
                                return Observable.error(throwable);
                            }
                        });
                    }
                })
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        Log.print("doOnSubscribe");
                    }
                })
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.print("onSubscribe");
                    }

                    @Override
                    public void onNext(@NonNull Object obj) {
                        Log.print("onNext", obj);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.print(e);
                    }

                    @Override
                    public void onComplete() {
                        Log.print("onComplete");
                    }
                });
    }
}
